﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GeneralDFS.DataEntity.Nodes;
using GeneralDFS.DataEntity.IO;

namespace GeneralDFS.BusinessLogical.IO
{
    public class BlockMap
    {
        private readonly IDictionary<FileBlockMetaData, FileBlockInfo> _blocks;

        public BlockMap()
        {
            _blocks=new SortedDictionary<FileBlockMetaData, FileBlockInfo>();
        }

        public FileBlockInfo GetStoredBlock(FileBlockMetaData fileBlockMetaData)
        {
            if (_blocks.ContainsKey(fileBlockMetaData))
            {
                return _blocks[fileBlockMetaData];
            }
            return null;
        }

        public FileBlockInfo AddBlockInfo(FileBlockInfo fileBlockInfo)
        {
            if (_blocks.ContainsKey(fileBlockInfo))
            {
                var blockInfo = _blocks[fileBlockInfo];
                if (blockInfo != fileBlockInfo)
                {
                    blockInfo = fileBlockInfo;
                    _blocks.Remove(fileBlockInfo);
                    _blocks.Add(blockInfo, blockInfo);
                }
            }
            else
            {
                _blocks.Add(fileBlockInfo, fileBlockInfo);
            }
            return fileBlockInfo;
        }

        public void RemoveBlock(FileBlockMetaData blockMetaData)
        {
            if (_blocks.ContainsKey(blockMetaData))
            {
                var fileBlockInfo = _blocks[blockMetaData];
                if(fileBlockInfo==null) return;
                for (var i = fileBlockInfo.NumNodes()-1; i>=0; i--)
                {
                    var dataNode = fileBlockInfo.GetDataNodeInfo(i);
                    dataNode.RemoveBlock(fileBlockInfo);
                }
                _blocks.Remove(blockMetaData);
            }
        }

        public int Count()
        {
            return _blocks.Count;
        }

        public int NumNodes(FileBlockMetaData fileBlockMetaData)
        {
            return _blocks[fileBlockMetaData].NumNodes();
        }

        public void Close()
        {
            _blocks.Clear();
        }
    }
}
